#pragma once
#include "base/core/point2.h"

template<typename TYPE = int>
class BaseRect
{
public:
    TYPE left, top, right, bottom;

public:
    BaseRect() {}
    BaseRect(TYPE left_value,
         TYPE top_value,
         TYPE right_value,
         TYPE bottom_value) 
	{
        left   = left_value;
        top    = top_value;
        right  = right_value;
        bottom = bottom_value;    
    }

    Point2<TYPE> GetPosition() const 
	{
        return Point2<TYPE>(left, top);
    }

    TYPE GetWidth() const 
	{
        return right - left;
    }

    TYPE GetHight() const 
	{
        return bottom - top;
    }

    bool IsIntersection(const BaseRect<TYPE>& rect) const 
	{
        if (right > rect.left
         && left  < rect.right
         && bottom > rect.top
         && top    < rect.bottom) 
		{
            return true;
        } 
		else 
		{
            return false;
        }
    }

    BaseRect<TYPE> GetIntersection(const BaseRect<TYPE>& rect) const 
	{
        if (right > rect.left
            && left  < rect.right
            && bottom > rect.top
            && top < rect.bottom) 
		{
            BaseRect tmp;
            tmp.left = (left > rect.left) ? left : rect.left;
            tmp.top  = (top > rect.top) ? top : rect.top;
            tmp.right = (right < rect.right) ? right : rect.right;
            tmp.bottom = (bottom < rect.bottom) ? bottom : rect.bottom;
            return tmp;
        } 
		else 
		{
            return BaseRect((TYPE)0, (TYPE)0, (TYPE)0, (TYPE)0);
        }
    }

    BaseRect<TYPE>& Offset(const Point2<TYPE>& point) const 
	{
        left   += point.x;
        top    += point.y;
        right  += point.x;
        bottom += point.y;
        return *this;
    }

    bool IsInRect(Point2<TYPE>& point) const 
	{
        if (left > point.x
         || right <= point.x
         || top > point.y
         || bottom <= point.y) 
		{
            return false;
        } 
		else 
		{
            return true;
        }
    }

    BaseRect<TYPE>& operator=(const BaseRect<TYPE>& rect)
	{    
        left   = rect.left;
        top    = rect.top;
        right  = rect.right;
        bottom = rect.bottom;
        return *this;
    }

    bool operator==(const BaseRect<TYPE>& rect) const 
	{
        if (left   == rect.left
         && right  == rect.right
         && top    == rect.top
         && bottom == rect.bottom) 
		{
            return true;
        } 
		else 
		{
            return false;
        }
    }

    bool operator!=(const BaseRect<TYPE>& rect) const 
	{
        return !operator==(rect);
    }

    BaseRect<TYPE> operator*(TYPE scalar) const 
	{
        return BaseRect<TYPE>(left*scalar, top*scalar, right*scalar, bottom*scalar);
    }

    const BaseRect<TYPE>& operator*=(TYPE scalar) 
	{
        left   *= scalar;
        top    *= scalar;
        right  *= scalar;
        bottom *= scalar;
        return *this;
    }
};

